Page({
  data: {
    nodes: [],        // 节点数据
    selectedId: -1,   // 当前选中节点ID
    nextId: 2,        // 下一个可用节点ID
    isDragging: false,// 拖拽状态
    dragOffset: { x: 0, y: 0 },
    currentShape: 'rect',
    canvasWidth: 600,   // 明确声明画布宽度
    canvasOffset: { x: 0, y: 0 }, // 新增画布偏移量
    startPos: { x: 0, y: 0 },     // 触摸起始位置
    isDraggingCanvas: false,       // 是否正在拖动画布
    editNode: {
      show: false,
      x: 0,
      y: 0,
      width: 100,
      height: 50,
      text: '',
      nodeId: -1
    },
    keyboardHeight: 0,
  },

  onLoad(options) {
    wx.onKeyboardHeightChange(res => {
      this.setData({ 
        keyboardHeight: res.height + 20 // 增加20rpx间距
      });
    });
    this.initDemoData(options.id);

    this.ctx = wx.createCanvasContext('mindmapCanvas'); 
  },

  // 修改点击事件处理
  onCanvasTap(e) {
    const physicalX = e.changedTouches[0].x;
    const physicalY = e.changedTouches[0].y;
    const logicPos = {
      x: physicalX - this.data.canvasOffset.x,
      y: physicalY - this.data.canvasOffset.y
    };

    const selectedNode = this.findNodeAtPosition(logicPos);
    
    if (selectedNode) {
      const screenX = selectedNode.x + this.data.canvasOffset.x ;
      const screenY = selectedNode.y + this.data.canvasOffset.y ; // 25为高度偏移
      this.setData({
        selectedId: selectedNode.id,
        editNode: {
          show: true,
          x: screenX - 50, // 矩形宽度100，左移50居中
          y: screenY - 25, // 矩形高度50，上移25居中
          width: 100,
          height: 50,
          text: selectedNode.text,
          nodeId: selectedNode.id
        }
      });
      
      // 延迟触发输入框聚焦
      setTimeout(() => {
        this.setData({ 'editNode.focus': true });
      }, 100);
    } else {
      this.closeEdit();
    }
  },

    // 新增编辑相关方法
    closeEdit() {
      this.setData({ 
        selectedId: -1,
        'editNode.show': false 
      });
    },
  
    onNodeInput(e) {
      this.setData({
        'editNode.text': e.detail.value
      });
    },
  
    onNodeConfirm() {
      const nodes = this.data.nodes.map(node => {
        if (node.id === this.data.editNode.nodeId) {
          return { ...node, text: this.data.editNode.text };
        }
        return node;
      });
      
      this.setData({
        nodes,
        'editNode.show': false
      }, () => {
        this.drawMindmap();
        wx.hideKeyboard();
      });
    },

  // 初始化示例数据（带实际坐标）
  initDemoData(id) {
    const demos = {
      1: {
        nodes: [
          { 
            id: 1, 
            x: 200, 
            y: 200, 
            text: '中心主题', 
            children: [], 
            parentId: null 
          }
        ],
        nextId: 2
      },
    };
    
    const data = demos[id] || { nodes: [], nextId: 1 };
    this.setData({
      nodes: data.nodes.map(n => ({ ...n, isSelected: false })), // 初始化选中状态
      nextId: data.nextId
    }, () => this.drawMindmap());
  },

 // 绘制导图（优化连接线）
drawMindmap() {
  this.ctx.clearRect(0, 0, this.data.canvasWidth, 800);
  this.ctx.save();
  this.ctx.translate(this.data.canvasOffset.x, this.data.canvasOffset.y);

  // 在drawMindmap方法中优化连接线样式
this.ctx.setStrokeStyle('#99aab5');
this.ctx.setLineWidth(2);
this.ctx.setLineCap('round');

  // 先绘制所有连接线（添加平滑处理）
  this.data.nodes.forEach(node => {
    if (node.children.length > 0) {
      node.children.forEach(childId => {
        const child = this.getNodeById(childId);
        if (child) {
          // 使用贝塞尔曲线
          this.ctx.beginPath();
          this.ctx.moveTo(node.x + 50, node.y); // 从节点右侧出发
          const cp1x = node.x + 70;
          const cp1y = node.y;
          const cp2x = child.x - 70;
          const cp2y = child.y;
          this.ctx.bezierCurveTo(
            cp1x, cp1y,
            cp2x, cp2y,
            child.x - 50, child.y // 连接到子节点左侧
          );
          this.ctx.stroke();
        }
      });
    }
  });

  // 绘制所有节点
  this.data.nodes.forEach(node => this.drawNode(node));
  
  this.ctx.restore();
  this.ctx.draw();
},

  // 统一形状绘制
  drawNode(node) {
    const isSelected = node.id === this.data.selectedId;
    this.ctx.save();
    // 在drawNode方法中优化节点样式
this.ctx.shadowOffsetX = 2;
this.ctx.shadowOffsetY = 2;
this.ctx.shadowBlur = 4;
this.ctx.shadowColor = 'rgba(0,0,0,0.1)';
    
    // 公共样式
    this.ctx.setFillStyle(isSelected ? '#e6f3ff' : '#fff');
    this.ctx.setStrokeStyle(isSelected ? '#1890ff' : '#666');
    this.ctx.setLineWidth(2);

    // 形状绘制
    this.drawRect(node);

    // 文字绘制
    this.ctx.setFontSize(14);
    this.ctx.setFillStyle('#333');
    this.ctx.setTextAlign('center');
    this.ctx.fillText(node.text, node.x, node.y + 5);
    
    this.ctx.restore();
  },

  drawRect(node) {
    const width = 100;
    const height = 50;
    this.ctx.beginPath();
    this.ctx.rect(node.x - width/2, node.y - height/2, width, height);
    this.ctx.fill();
    this.ctx.stroke();
  },

 // 添加子节点（水平布局）
addChildNode() {
  // 保持输入框焦点
  const keepFocus = this.data.editNode.show;

  const node = this.getSelectedNode();
  if (!node) return;

  const newNode = {
    id: this.data.nextId,
    x: node.x,
    y: node.y,
    text: '',
    shape: this.data.currentShape,
    children: [],
    parentId: node.id
  };

  this.updateNodes(node, newNode, keepFocus);
},

  // 添加同级节点（新增方法）
  addSiblingNode() {
    const current = this.getSelectedNode();
    if (!current) return;

    const parent = this.getNodeById(current.parentId);
    if (!parent) {
      wx.showToast({ title: '根节点无法添加同级', icon: 'none' });
      return;
    }

    const newNode = {
      id: this.data.nextId,
      x: current.x,
      y: current.y,
      text: '',
      shape: this.data.currentShape,
      children: [],
      parentId: parent.id
    };

    this.updateNodes(parent, newNode);
  },

    // 删除节点（递归删除子节点）
    deleteNode() {
      const node = this.getSelectedNode();
      if (!node) {
        wx.showToast({ title: '请先选择节点', icon: 'none' });
        return;
      }
      const parent = this.getNodeById(node.parentId);
      if (!parent) {
        wx.showToast({ title: '根节点无法删除', icon: 'none' });
        return;
      }
    
      let nodes = [...this.data.nodes];
    
      // 1. 从父节点children数组中移除当前节点ID
      if (node.parentId !== null) {
        const parent = nodes.find(n => n.id === node.parentId);
        if (parent) {
          parent.children = parent.children.filter(id => id !== node.id);
        }
      }
    
      // 2. 递归删除当前节点及其所有子节点
      const deleteChildren = (id) => {
        nodes = nodes.filter(n => n.id !== id);
        const children = nodes.filter(n => n.parentId === id);
        children.forEach(child => deleteChildren(child.id));
        return nodes;
      };
    
      deleteChildren(node.id);
    
      this.setData({
        nodes: nodes,
        selectedId: -1
      }, () => this.drawMindmap());
    },

  // 绘制连接线
  drawConnection(fromNode, toNode) {
    this.ctx.beginPath();
    this.ctx.moveTo(fromNode.x, fromNode.y + 30);
    this.ctx.lineTo(toNode.x, toNode.y - 30);
    this.ctx.setStrokeStyle('#999');
    this.ctx.setLineWidth(1);
    this.ctx.stroke();
  },

// 修改updateNodes方法
updateNodes(parent, newNode, keepFocus = false) {
  // 保存当前编辑状态
  const editState = { ...this.data.editNode };
  
  const updatedNodes = JSON.parse(JSON.stringify(this.data.nodes));
  const realParent = updatedNodes.find(n => n.id === parent.id);
  realParent.children.push(newNode.id);
  updatedNodes.push(newNode);

  // 从根节点开始重新布局
  const rootNode = updatedNodes.find(n => n.parentId === null);
  this.fullLayout(rootNode, updatedNodes);

  // 计算需要保持的编辑状态
  const newEditState = keepFocus ? {
    ...editState,
    nodeId: newNode.id,
    text: newNode.text,
    show: true,
    x: newNode.x + this.data.canvasOffset.x - 50,
    y: newNode.y + this.data.canvasOffset.y - 25
  } : editState;

  this.setData({
    nodes: updatedNodes,
    nextId: this.data.nextId + 1,
    editNode: newEditState
  }, () => {
    this.drawMindmap();
    
    // 自动滚动到新节点位置
    const targetX = newNode.x - wx.getSystemInfoSync().windowWidth / 2;
    const targetY = newNode.y - wx.getSystemInfoSync().windowHeight / 2;
    
    this.setData({
      canvasOffset: {
        x: -targetX,
        y: -targetY
      }
    }, () => {
      this.drawMindmap();
      
      // 延迟设置焦点确保生效
      if (keepFocus) {
        setTimeout(() => {
          this.setData({ 
            selectedId: newNode.id,
            'editNode.focus': true 
          });
        }, 300);
      }
    });
  });
},

// 修改adjustSiblingNodes方法为垂直排列
adjustSiblingNodes(parent, nodes) {
  const siblings = nodes.filter(n => n.parentId === parent.id);
  const numSiblings = siblings.length;
  if (numSiblings === 0) return;

  const HORIZONTAL_SPACING = 120; // 水平间距保持不变
  const VERTICAL_SPACING = 80;    // 垂直间距
  
  // 计算起始Y坐标（使子节点垂直居中）
  const startY = parent.y - (numSiblings - 1) * VERTICAL_SPACING / 2;

  // 设置所有子节点相同X坐标，Y按垂直排列
  siblings.forEach((sibling, index) => {
    sibling.x = parent.x + HORIZONTAL_SPACING;
    sibling.y = startY + index * VERTICAL_SPACING;
  });

  // 递归调整子节点时保持垂直分支
  siblings.forEach(sibling => {
    this.adjustChildNodes(sibling, nodes, HORIZONTAL_SPACING);
  });
},

// 修改按钮点击处理方法
onToolButtonClick(e) {
  // 阻止默认行为和冒泡
  e.preventDefault();
  e.stopPropagation();
  
  // 保持键盘显示状态
  if (this.data.editNode.show) {
    this.setData({ 'editNode.focus': true }, () => {
      this.handleButtonAction(e);
    });
  } else {
    this.handleButtonAction(e);
  }
},

handleButtonAction(e) {
  const type = e.currentTarget.dataset.type;
  switch(type) {
    case 'addChild':
      setTimeout(() => this.addChildNode(), 150);
      break;
    case 'addSibling':
      setTimeout(() => this.addSiblingNode(), 150);
      break;
    case 'delete':
      this.deleteNode();
      break;
  }
},

// 修改adjustChildNodes保持垂直分支
adjustChildNodes(node, nodes, baseSpacing = 120) {
  const children = nodes.filter(n => n.parentId === node.id);
  if (children.length === 0) return;

  const depth = this.getNodeDepth(node);
  const HORIZONTAL_SPACING = baseSpacing * 0.9; // 每层间距递减
  const VERTICAL_SPACING = 80 + depth * 20;     // 基础垂直间距

  // 计算起始Y坐标
  const totalHeight = (children.length - 1) * VERTICAL_SPACING;
  const startY = node.y - totalHeight / 2;

  children.forEach((child, index) => {
    child.x = node.x + HORIZONTAL_SPACING;  // 保持相同X坐标
    child.y = startY + index * VERTICAL_SPACING;
    this.adjustChildNodes(child, nodes, HORIZONTAL_SPACING);
  });
},

// 获取节点深度（新增方法）
getNodeDepth(node) {
  let depth = 0;
  let current = node;
  while (current.parentId !== null) {
    depth++;
    current = this.data.nodes.find(n => n.id === current.parentId);
  }
  return depth;
},

  // 其他辅助方法
  getNodeById(id) {
    return this.data.nodes.find(n => n.id === id);
  },

  getSelectedNode() {
    return this.data.nodes.find(n => n.id === this.data.selectedId);
  },

  // 形状切换功能
  changeShape(e) {
    const shape = e.currentTarget.dataset.shape;
    this.setData({ currentShape: shape });
  },

  // 碰撞检测（适配矩形）
  findNodeAtPosition(pos) {
    return this.data.nodes.find(node => {
      const actualX = node.x; // 逻辑坐标已包含偏移
      const actualY = node.y;
      
       return pos.x > actualX-40 && pos.x < actualX+40 &&
               pos.y > actualY-25 && pos.y < actualY+25;
    });
  },

  onTouchStart(e) {
    if (e.target.dataset.toolbar) return;
    
    // 隐藏键盘逻辑移到此处
    if (this.data.editNode.show) {
      wx.hideKeyboard();
      this.closeEdit();
    }
  
    this.setData({
      startPos: {
        x: e.touches[0].clientX,
        y: e.touches[0].clientY
      },
      isDraggingCanvas: true
    });
  },
  
    onTouchMove(e) {
      if (!this.data.isDraggingCanvas) return;
  
      const currentX = e.touches[0].clientX;
      const currentY = e.touches[0].clientY;
      
      // 计算偏移量差值
      const deltaX = currentX - this.data.startPos.x;
      const deltaY = currentY - this.data.startPos.y;
  
      // 更新画布偏移量
      this.setData({
        canvasOffset: {
          x: this.data.canvasOffset.x + deltaX,
          y: this.data.canvasOffset.y + deltaY
        },
        startPos: { x: currentX, y: currentY }
      });
  
      // 立即重绘
      this.drawMindmap();
    },

// 修改触摸结束处理
onTouchEnd() {
  if (this.data.isDraggingCanvas) {
    this.setData({ isDraggingCanvas: false });
    this.checkCollisionAndAdjust(); // 增加位置调整
  }
},
 
// 优化后的碰撞检测
isColliding(nodeA, nodeB) {
  const NODE_WIDTH = 100;
  const NODE_HEIGHT = 50;
  return !(
    nodeA.x + NODE_WIDTH/2 < nodeB.x - NODE_WIDTH/2 ||
    nodeA.x - NODE_WIDTH/2 > nodeB.x + NODE_WIDTH/2 ||
    nodeA.y + NODE_HEIGHT/2 < nodeB.y - NODE_HEIGHT/2 ||
    nodeA.y - NODE_HEIGHT/2 > nodeB.y + NODE_HEIGHT/2
  );
},

// 改进后的碰撞检测方法
checkCollisionAndAdjust(newNode) {
  const NODE_SPACE = 80; // 垂直方向最小间距
  let hasCollision = true;
  let adjustCount = 0;
  const ADJUST_STEP = 30; // 调整步长

  while (hasCollision && adjustCount < 8) { // 增加尝试次数
    hasCollision = false;
    
    this.data.nodes.forEach(existingNode => {
      if (existingNode.id === newNode.id || existingNode.parentId === newNode.id) return;
      
      if (this.isColliding(newNode, existingNode)) {
        hasCollision = true;
        const deltaY = existingNode.y > newNode.y ? -ADJUST_STEP : ADJUST_STEP;
        this.adjustBranchPosition(newNode, deltaY);
      }
    });
    
    adjustCount++;
  }
},
// 改进分支调整方法
adjustBranchPosition(node, deltaY) {
  const updatedNodes = this.data.nodes.map(n => ({...n})); // 创建新数组
  
  const updateNode = (n) => {
    const target = updatedNodes.find(item => item.id === n.id);
    target.y += deltaY;
    this.getChildren(target, updatedNodes).forEach(child => updateNode(child));
  };

  updateNode(node);
  
  this.setData({ nodes: updatedNodes }); // 重要！更新数据
  this.drawMindmap();
},


// 获取所有子节点
getChildren(node, nodes) {
  return nodes.filter(n => n.parentId === node.id);
},

// 获取节点深度
getNodeDepth(node) {
  let depth = 0;
  let current = node;
  while (current.parentId !== null) {
    depth++;
    current = this.data.nodes.find(n => n.id === current.parentId);
  }
  return depth;
},

// 修改全量布局方法
fullLayout(rootNode, nodes) {
  const walk = (node, level) => {
    const children = nodes.filter(n => n.parentId === node.id);
    const spacingX = 180; // 固定水平间距
    const verticalSpacing = 100 + level * 20; // 垂直间距随层级变化

    children.forEach((child, index) => {
      // 垂直居中排列
      child.x = node.x + spacingX;
      child.y = node.y + (index - children.length/2) * verticalSpacing;
      walk(child, level + 1);
    });

    // 平衡布局
    if (children.length > 0) {
      const minY = Math.min(...children.map(c => c.y));
      const maxY = Math.max(...children.map(c => c.y));
      const centerY = (minY + maxY) / 2;
      children.forEach(child => {
        child.y += node.y - centerY;
        this.adjustSubtree(child, node.y - centerY, nodes);
      });
    }
  };

  walk(rootNode, 1);
},

// 新增子树调整方法
adjustSubtree(node, deltaY, nodes) {
  node.y += deltaY;
  nodes.filter(n => n.parentId === node.id).forEach(child => {
    this.adjustSubtree(child, deltaY, nodes);
  });
},

// 改进碰撞检测方法
checkCollisionAndAdjust() {
  const NODE_SPACE = 120; // 节点间最小间距
  let hasCollision = true;
  let retryCount = 0;

  while (hasCollision && retryCount < 5) {
    hasCollision = false;
    const nodes = JSON.parse(JSON.stringify(this.data.nodes));

    // 按层级分组检测
    const levelMap = new Map();
    nodes.forEach(node => {
      const level = this.getNodeDepth(node);
      if (!levelMap.has(level)) levelMap.set(level, []);
      levelMap.get(level).push(node);
    });

    // 层级内检测碰撞
    levelMap.forEach((levelNodes, level) => {
      levelNodes.sort((a, b) => a.y - b.y);
      
      for (let i = 1; i < levelNodes.length; i++) {
        const prev = levelNodes[i-1];
        const current = levelNodes[i];
        
        if (current.y - prev.y < NODE_SPACE) {
          hasCollision = true;
          const adjust = NODE_SPACE - (current.y - prev.y);
          this.adjustBranchVertical(current, adjust, nodes);
        }
      }
    });

    if (hasCollision) {
      this.setData({ nodes }, () => this.drawMindmap());
      retryCount++;
    }
  }
},

// 改进分支调整方法
adjustBranchVertical(node, deltaY, nodes) {
  const update = (n) => {
    const target = nodes.find(item => item.id === n.id);
    target.y += deltaY;
    nodes.filter(child => child.parentId === target.id)
         .forEach(child => update(child));
  };
  update(node);
},

// 新增分层布局算法
fullLayout(rootNode, nodes) {
  // 计算树形结构数据
  const treeData = this.buildTreeStructure(rootNode, nodes);
  
  // 执行分层布局计算
  this.calculateLayout(treeData);
  
  // 应用布局坐标到节点数据
  this.applyLayout(treeData, nodes);
},

// 构建树形结构（带子树信息）
buildTreeStructure(node, nodes) {
  const children = nodes.filter(n => n.parentId === node.id)
                       .map(child => this.buildTreeStructure(child, nodes));
  return {
    id: node.id,
    width: 100,  // 节点宽度
    height: 50,  // 节点高度
    x: node.x,
    y: node.y,
    children,
    subtreeWidth: 0,  // 子树总宽度
    subtreeHeight: 0  // 子树总高度
  };
},
// 核心布局算法
calculateLayout(node) {
  if (!node.children.length) {
    node.subtreeWidth = node.width;
    node.subtreeHeight = node.height;
    return;
  }

  // 递归计算子节点布局
  node.children.forEach(child => this.calculateLayout(child));

  // 垂直布局参数
  const horizontalSpacing = 120;  // 水平间距（父节点到子节点的水平距离）
  const verticalSpacing = 80;     // 垂直间距（子节点之间的间距）

  // 计算所有子节点的总高度
  const childrenHeight = node.children.reduce((sum, child) => sum + child.subtreeHeight, 0) +
                        (node.children.length - 1) * verticalSpacing;

  // 设置第一个子节点的起始Y位置（垂直居中）
  let currentY = -childrenHeight / 2;

  // 排列子节点
  node.children.forEach(child => {
    // 子节点X位置：父节点右侧固定间距
    child.x = horizontalSpacing;
    // 子节点Y位置：累计当前高度
    child.y = currentY + child.subtreeHeight / 2;
    
    // 更新当前Y位置（累加子节点高度和间距）
    currentY += child.subtreeHeight + verticalSpacing;
  });

  // 更新父节点子树尺寸
  node.subtreeWidth = horizontalSpacing + 
    Math.max(...node.children.map(c => c.subtreeWidth)); // 取最宽子树的宽度
  node.subtreeHeight = Math.max(
    node.height,
    childrenHeight
  );
},

// 应用布局坐标
applyLayout(treeData, nodes, parentX = 0, parentY = 0) {
  const node = nodes.find(n => n.id === treeData.id);
  // 节点最终位置 = 父节点位置 + 相对位置
  node.x = parentX + treeData.x;
  node.y = parentY + treeData.y;

  // 递归应用子节点布局（子节点的parentX是当前节点的x）
  treeData.children.forEach(child => {
    this.applyLayout(child, nodes, node.x, node.y);
  });
},
});